package org.bing.engine.controller.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.bing.engine.common.remoting.RemotingProxyFactory;
import org.bing.engine.core.domain.Node;
import org.bing.engine.utility.helper.StringHelper;

public class RemoteFactory {
    private static final Map<String, Object> services = new ConcurrentHashMap<String, Object>();
    private RemotingProxyFactory proxyFactory;
    private String serviceUrl;

    public void setServiceUrl(String url) {
        this.serviceUrl = url;
    }

    public void setProxyFactory(RemotingProxyFactory factory) {
        this.proxyFactory = factory;
    }

    @SuppressWarnings("unchecked")
    public <T> T getRemoteService(Node node, Class<T> clz) {
        String name = clz.getName();
        Object obj = services.get(name);
        if (obj == null) {
            obj = build(node, clz);
        }
        return (T) obj;
    }

    @SuppressWarnings("rawtypes")
    private synchronized Object build(Node node, Class clz) {
        String name = clz.getName();
        if (services.containsKey(name)) {
            return services.get(name);
        }
        Object obj = doBuild(node, clz);
        services.put(name, obj);
        return obj;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected Object doBuild(Node node, Class clz) {
        String url = serviceUrl;
        url = StringHelper.replaceWithProperty(url, "address", node.getAddress());
        url = StringHelper.replaceWithProperty(url, "port", String.valueOf(node.getPort()));
        url = url + "$";
        return proxyFactory.create(clz, url);
    }
}
